#include "config.h"

#include <clx/libECM.h>

#include "libms2sim.h"

#define N_STAT	30
#define INDEX_NEXT(i)	((i + 1) % N_STAT)

typedef struct {
	ecm_uint64	interarrivals[N_STAT];
	ecm_uint32	ptr;
	ecm_uint32	cnt;
	ecm_uint64	last_arrival;
} iastat_t;

msl_iastat_t
msl_iastat_create(void)
{
	iastat_t	*iastat;

	iastat = (iastat_t *)ecm_malloc(sizeof(iastat_t));
	if (iastat == NULL)
		return NULL;
	iastat->ptr = iastat->cnt = 0;
	iastat->last_arrival = 0;

	return iastat;
}

void
msl_iastat_add(msl_iastat_t msl_iastat, unsigned long long arrival_time)
{
	iastat_t	*iastat = (iastat_t *)msl_iastat;

	if (iastat->last_arrival > 0) {
		ECMASSERT(arrival_time >= iastat->last_arrival);
		iastat->interarrivals[iastat->ptr] = arrival_time - iastat->last_arrival;
		if (iastat->cnt < N_STAT)
			iastat->cnt++;
		iastat->ptr = (iastat->ptr + 1) % N_STAT;
	}

	iastat->last_arrival = arrival_time;
}

unsigned int
msl_iastat_get(msl_iastat_t msl_iastat)
{
	iastat_t	*iastat = (iastat_t *)msl_iastat;
	ecm_uint32	total = 0;
	ecm_uint32	i;

	if (iastat == NULL)
		return 0;

	if (iastat->cnt == 0)
		return 0;

	for (i = 0; i < iastat->cnt; i++) {
		total += (ecm_uint32)iastat->interarrivals[i];
	}
	return (unsigned int)(total / iastat->cnt);
}

void
msl_iastat_free(msl_iastat_t msl_iastat)
{
	iastat_t	*iastat = (iastat_t *)msl_iastat;

	if (iastat == NULL)
		return;

	ecm_free(iastat);
}
